﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using UtilZ.Dotnet.WindowsDesktopEx.Base;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace UtilZ.Dotnet.WindowsDesktopEx.WPF
{
    /// <summary>
    /// 通知管理器
    /// </summary>
    public class NotifyManager : IDisposable
    {
        private readonly static List<NotifyManager> _managerList = null;
        private readonly static DispatcherTimer _timer = null;
        private static bool _timerStoped = true;


        /// <summary>
        /// 默认管理器
        /// </summary>
        public static NotifyManager Default = null;


        static NotifyManager()
        {
            _managerList = new List<NotifyManager>();
            _timer = new DispatcherTimer();
            _timer.Tick += _timer_Tick;
            _timer.Interval = TimeSpan.FromMilliseconds(100);

            Default = new NotifyManager();
        }

        private static void _timer_Tick(object sender, EventArgs e)
        {
            int count = 0;
            lock (_managerList)
            {
                for (int i = 0; i < _managerList.Count; i++)
                {
                    count += _managerList[i].Check();
                }

                if (count <= 0)
                {
                    _timer.Stop();
                    _timerStoped = true;
                }
            }
        }





        private double _opacityStep = -1;


        private int _margin = 2;
        /// <summary>
        /// 多个通知之间间隔,单位:像素
        /// </summary>
        public int Margin
        {
            get { return this._margin; }
            set { this._margin = value; }
        }

        private int _padding = 3;
        /// <summary>
        /// 单个通知与屏幕边缘距离,单位:像素
        /// </summary>
        public int Padding
        {
            get { return this._padding; }
            set { this._padding = value; }
        }

        /*
        private UIDirection _dockingDirection = UIDirection.Right;
        /// <summary>
        /// 停靠方向
        /// </summary>
        public UIDirection DockingDirection
        {
            get { return this._dockingDirection; }
            set { this._dockingDirection = value; }
        }

        private UIDirection _anmimalMoveDirection = UIDirection.Right;
        /// <summary>
        /// 动画移动方向
        /// </summary>
        public UIDirection AnmimalMoveDirection
        {
            get { return this._anmimalMoveDirection; }
            set { this._anmimalMoveDirection = value; }
        }
        */

        private long _anmimalDuration = 500;
        /// <summary>
        /// 动画持续时长,单位毫秒
        /// </summary>
        public long AnmimalDuration
        {
            get { return this._anmimalDuration; }
            set
            {
                if (value > 0)
                {
                    this._opacityStep = Math.Round(1.0d / (value / _timer.Interval.TotalMilliseconds), 2);
                }
                else
                {
                    this._opacityStep = -1.0D;
                }

                this._anmimalDuration = value;
            }
        }

        private long _duration = 5000;
        /// <summary>
        /// 显示时长,单位:毫秒
        /// </summary>
        public long Duration
        {
            get { return this._duration; }
            set { this._duration = value; }
        }



        private readonly List<NotifyWindow> _frmList = new List<NotifyWindow>();
        /// <summary>
        /// 
        /// </summary>
        public NotifyManager()
        {
            this._opacityStep = Math.Round(1.0d / (this._anmimalDuration / _timer.Interval.TotalMilliseconds), 2);

            lock (_managerList)
            {
                _managerList.Add(this);

                if (_timerStoped)
                {
                    _timer.Start();
                    _timerStoped = false;
                }
            }
        }




        private int Check()
        {
            bool removed = false;
            double totalHeight = 0;//, totalWidth = 0;
            int margin = 0;

            for (int i = 0; i < this._frmList.Count;)
            {
                if (this._frmList[i].Check())
                {
                    this._frmList[i].Loaded -= this.Window_Loaded;
                    this._frmList.RemoveAt(i);
                    if (i >= this._frmList.Count)
                    {
                        break;
                    }
                    else
                    {
                        removed = true;
                    }
                }
                else
                {
                    if (removed)
                    {
                        if (totalHeight == 0)
                        {
                            for (int j = 0; j < i; j++)
                            {
                                totalHeight += this._frmList[j].ActualHeight;
                            }

                            margin = i * this._margin;
                        }

                        this._frmList[i].UpdateLocaion(totalHeight, margin);
                        totalHeight += this._frmList[i].ActualHeight;
                        margin += this._margin;
                    }

                    i++;
                }
            }

            return this._frmList.Count;
        }



        private void PrimitiveNotify(NotifyItem item)
        {
            var window = new NotifyWindow(item, this._opacityStep, this._padding);
            window.Loaded += this.Window_Loaded;
            window.Show();
            this._frmList.Add(window);


            if (_timerStoped)
            {
                lock (_managerList)
                {
                    if (_timerStoped)
                    {
                        _timer.Start();
                        _timerStoped = false;
                    }
                }
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //double totalHeight = 0, totalWidth = 0;
            //if (this._frmList.Count > 0)
            //{
            //    switch (this._dockingDirection)
            //    {
            //        case UIDirection.Left:
            //        case UIDirection.Right:
            //            totalHeight = this._frmList.Sum(t => { return t.ActualHeight; });
            //            break;
            //        case UIDirection.Top:
            //        case UIDirection.Bottom:
            //            totalWidth = this._frmList.Sum(t => { return t.ActualWidth; });
            //            break;
            //    }
            //}

            var window = (NotifyWindow)sender;
            double totalHeight = 0;
            if (this._frmList.Count > 0)
            {
                totalHeight = this._frmList.Sum(t => { return t.ActualHeight; });
            }
            window.UpdateLocaion(totalHeight, this._frmList.Count * this._margin);
        }

        /// <summary>
        /// 发送通知
        /// </summary>
        /// <param name="item">通知项</param>
        public void Notify(NotifyItem item)
        {
            if (item == null)
            {
                return;
            }

            this.PrimitiveNotify(item);
        }

        /// <summary>
        /// 发送OK通知
        /// </summary>
        /// <param name="text">通知文本</param>
        public void OK(string text)
        {
            this.PrimitiveNotify(new NotifyItem()
            {
                Text = text,
                BackgroundColor = System.Windows.Media.Brushes.Gray,
                MesageImage = OKImg,
                Duration = this._duration,
            });
        }

        /// <summary>
        /// 发送信息通知
        /// </summary>
        /// <param name="text">通知文本</param>
        public void Info(string text)
        {
            this.PrimitiveNotify(new NotifyItem()
            {
                Text = text,
                BackgroundColor = System.Windows.Media.Brushes.Green,
                MesageImage = InfoImg,
                Duration = this._duration,
            });
        }

        /// <summary>
        /// 发送告警通知
        /// </summary>
        /// <param name="text">通知文本</param>
        public void Warn(string text)
        {
            this.PrimitiveNotify(new NotifyItem()
            {
                Text = text,
                BackgroundColor = System.Windows.Media.Brushes.Goldenrod,
                MesageImage = WarnImg,
                Duration = this._duration,
            });
        }

        /// <summary>
        /// 发送错误通知
        /// </summary>
        /// <param name="text">通知文本</param>
        public void Error(string text)
        {
            this.PrimitiveNotify(new NotifyItem()
            {
                Text = text,
                BackgroundColor = System.Windows.Media.Brushes.Brown,
                MesageImage = ErrorImg,
                Duration = this._duration,
            });
        }

        /// <summary>
        /// 发送响铃通知
        /// </summary>
        /// <param name="text">通知文本</param>
        public void Ring(string text)
        {
            this.PrimitiveNotify(new NotifyItem()
            {
                Text = text,
                BackgroundColor = System.Windows.Media.Brushes.HotPink,
                MesageImage = RingImg,
                Duration = this._duration,
            });
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            lock (_managerList)
            {
                _managerList.Remove(this);

                if (_managerList.Count <= 0)
                {
                    _timer.Stop();
                    _timerStoped = true;
                    _timer.Dispatcher.DisableProcessing();
                }
            }
        }






        //private static System.Windows.Media.Brush ConvertToBitmapSource(System.Drawing.Bitmap image)
        //{
        //    return new ImageBrush(System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(image.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()));
        //}
        private static System.Windows.Media.ImageSource ConvertToBitmapSource(System.Drawing.Bitmap image)
        {
            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(image.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        }


        private static System.Windows.Media.ImageSource _OKImg = null;
        /// <summary>
        /// OK图片
        /// </summary>
        public static System.Windows.Media.ImageSource OKImg
        {
            get
            {
                if (_OKImg == null)
                {
                    _OKImg = ConvertToBitmapSource(ResourcesManger.ok);
                }

                return _OKImg;
            }
        }

        private static System.Windows.Media.ImageSource _infoImg = null;
        /// <summary>
        /// 信息图片
        /// </summary>
        public static System.Windows.Media.ImageSource InfoImg
        {
            get
            {
                if (_infoImg == null)
                {
                    _infoImg = ConvertToBitmapSource(ResourcesManger.info);
                }

                return _infoImg;
            }
        }

        private static System.Windows.Media.ImageSource _warnImg = null;
        /// <summary>
        /// 警告图片
        /// </summary>
        public static System.Windows.Media.ImageSource WarnImg
        {
            get
            {
                if (_warnImg == null)
                {
                    _warnImg = ConvertToBitmapSource(ResourcesManger.warning);
                }

                return _warnImg;
            }
        }

        private static System.Windows.Media.ImageSource _errorImg = null;
        /// <summary>
        /// 错误图片
        /// </summary>
        public static System.Windows.Media.ImageSource ErrorImg
        {
            get
            {
                if (_errorImg == null)
                {
                    _errorImg = ConvertToBitmapSource(ResourcesManger.error);
                }

                return _errorImg;
            }
        }

        private static System.Windows.Media.ImageSource _ringImg = null;
        /// <summary>
        /// 响铃图片
        /// </summary>
        public static System.Windows.Media.ImageSource RingImg
        {
            get
            {
                if (_ringImg == null)
                {
                    _ringImg = ConvertToBitmapSource(ResourcesManger.ring);
                }

                return _ringImg;
            }
        }

        private static System.Windows.Media.ImageSource _closeImg = null;
        /// <summary>
        /// 关闭图片
        /// </summary>
        public static System.Windows.Media.ImageSource CloseImg
        {
            get
            {
                if (_closeImg == null)
                {
                    _closeImg = ConvertToBitmapSource(ResourcesManger.close);
                }

                return _closeImg;
            }
        }


    }
}
